import utils from "@/utils/utils";

// 解析指令参数
function parseBinding(binding) {
  let options = {};

  if (typeof binding.value === "function") {
    options.callback = binding.value;
  } else if (typeof binding.value === "object") {
    options = { ...binding.value };
  }

  return options;
}
export function defineDirectives(app) {
  //监听挂载元素节点的尺寸变化
  app.directive("resize", {
    mounted(el, binding) {
      el.ob = new ResizeObserver((entries) => {
        for (const entry of entries) {
          if (entry.target === el) {
            if (binding.value && typeof binding.value === "function") {
              binding.value({
                height: entry.borderBoxSize[0]["blockSize"],
                width: entry.borderBoxSize[0]["inlineSize"],
              });
            }
          }
        }
      });
      el.ob.observe(el);
    },
    unmounted(el, binding) {
      if (el.ob) {
        el.ob.disconnect();
        el.ob = null;
        delete el.ob;
      }
    },
  });

  app.directive("load-more", {
    mounted(el, binding) {
      const {
        // 默认配置
        target = "", // 要监听的滚动容器选择器
        distance = 100, // 距离底部多少像素触发
        delay = 200, // 节流时间(ms)
        callback, // 必须传入的回调函数
        immediate = false, // 是否立即初始化
      } = parseBinding(binding);

      // 元素引用缓存
      let scrollContainer = null;
      let isLocked = false; // 加载锁防止重复触发

      // 获取实际滚动容器
      const getScrollContainer = () => {
        if (!scrollContainer) {
          scrollContainer = target ? el.querySelector(target) : el;
        }
        return scrollContainer;
      };

      // 触底检测逻辑
      const checkBottom = utils.debounce(() => {
        if (isLocked) return;

        const container = getScrollContainer();
        if (!container) return;

        const { scrollTop, scrollHeight, clientHeight } = container;
        const shouldLoad = scrollTop + clientHeight >= scrollHeight - distance;

        if (shouldLoad) {
          isLocked = true;
          Promise.resolve(callback?.()).finally(() => {
            isLocked = false;
          });
        }
      }, delay);

      // 初始化监听
      const init = () => {
        const container = getScrollContainer();
        if (!container) return;

        container.addEventListener("scroll", checkBottom);
        // 首次主动检查（适用于内容不满屏的情况）
        if (immediate) checkBottom();
      };

      // 清理监听
      const destroy = () => {
        const container = getScrollContainer();
        if (container) {
          container.removeEventListener("scroll", checkBottom);
        }
      };

      // 存储到元素属性以便更新和卸载
      el._loadMore = { init, destroy };

      // 延迟初始化确保 DOM 渲染完成
      setTimeout(init, 0);
    },

    updated(el, binding) {
      // 参数变化时重新初始化
      if (binding.value !== binding.oldValue) {
        el._loadMore?.destroy();
        el._loadMore?.init();
      }
    },

    beforeUnmount(el) {
      el._loadMore?.destroy();
    },
  });
}
